package org.softmed.rest.editor.comps.utils.list;

import java.awt.Color;
import java.awt.Container;
import java.awt.SystemColor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;

import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import net.miginfocom.swing.MigLayout;

import org.restlet.Client;
import org.restlet.data.Protocol;
import org.restlet.data.Response;
import org.softmed.rest.editor.EditorUtil;
import org.softmed.rest.editor.FilePathAware;
import org.softmed.rest.editor.FilePathProvider;
import org.softmed.rest.editor.commons.SwingUtil;
import org.softmed.rest.editor.commons.URIProvider;
import org.softmed.rest.editor.comps.SimpleEditor;
import org.softmed.rest.editor.comps.browser.InfoBar;
import org.softmed.rest.editor.comps.browser.NavBar;
import org.softmed.rest.editor.comps.browser.PagedList;
import org.softmed.rest.editor.comps.browser.SelectionListener;
import org.softmed.rest.editor.uri.URIUtil;
import org.softmed.rest.editor.xml.XStreamConfigurator;

import com.thoughtworks.xstream.XStream;

public class PagedListPanel extends JPanel implements ActionListener,
		FilePathAware {
	boolean settingValues = false;
	PagedList pagedList;

	InfoBar infoBar = new InfoBar();
	ItemList itemList;
	InfoBar bottomInfoBar = new InfoBar();

	XStream streamer = XStreamConfigurator.getXStream();
	Client client = new Client(Protocol.HTTP);

	String baseURI;

	URIProvider rootAdminURIProvider;

	public PagedListPanel(URIProvider rootAdminURIProvider,
			ActionListener listener) {

		this.rootAdminURIProvider = rootAdminURIProvider;
		itemList = new ItemList(rootAdminURIProvider, listener);
		// XStreamConfigurator.configurePagedListComplete(streamer);

		MigLayout layout = new MigLayout("left,insets 0");
		setLayout(layout);

		// add(infoBar, "wrap 0");
		add(itemList, "wrap 0");
		// add(bottomInfoBar);

		infoBar.getPages().addActionListener(this);
		infoBar.getNavBar().addNavButtonsActionListener(this);

		bottomInfoBar.getPages().addActionListener(this);
		bottomInfoBar.getNavBar().addNavButtonsActionListener(this);

	}

	public void setBaseClassURI(String baseURI) throws Throwable {
		this.baseURI = baseURI;
		openURI(baseURI + "?detailed");
	}

	public void setPagedList(PagedList plist) throws Throwable {
		settingValues = true;
		pagedList = plist;
		infoBar.setPagedList(plist);
		itemList.setPagedList(plist);
		bottomInfoBar.setPagedList(plist);
		settingValues = false;
	}

	protected void openURI(String uri) throws Throwable {
		try {
			EditorUtil.showUpdatePanel();
			Response response = client.get(uri);
			EditorUtil.hideUpdatePanel();
			if (response.getStatus().getCode() != 200)
				throw new RuntimeException("Couldn't GET at uri: " + uri);
			String xml = response.getEntity().getText();
			PagedList plist = (PagedList) streamer.fromXML(xml);

			URIUtil.decodeAmpersands(plist);

			setPagedList(plist);
		} catch (Throwable t) {
			EditorUtil.hideUpdatePanel();
			t.printStackTrace();
			JOptionPane.showMessageDialog(this, t.getMessage(), "Error",
					JOptionPane.ERROR_MESSAGE);
			throw t;
		}

	}

	public void refresh() throws Throwable {
		if (pagedList != null)
			openURI(baseURI + "?detailed&page="
					+ pagedList.getCurrentPageNumber());
		else
			openURI(baseURI + "?detailed");
	}

	public void goToLastPage() throws Throwable {
		if (pagedList != null && pagedList.getLastURI() != null)
			openURI(pagedList.getLastURI() + "&detailed");
		else
			openURI(baseURI + "?detailed");
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (settingValues)
			return;

		try {

			Object source = e.getSource();
			if (source == infoBar.getPages()) {
				Integer selectedPaged = (Integer) infoBar.getPages()
						.getSelectedItem();
				openURI(baseURI + "?detailed&page=" + selectedPaged);
				return;
			}

			if (source == bottomInfoBar.getPages()) {
				Integer selectedPaged = (Integer) bottomInfoBar.getPages()
						.getSelectedItem();
				openURI(baseURI + "?detailed&page=" + selectedPaged);
				return;
			}

			if (source == infoBar.getNavBar().getFirst()) {
				openURI(pagedList.getFirstURI());
				return;
			}

			if (source == infoBar.getNavBar().getPrevious()) {
				openURI(pagedList.getPreviousURI());
				return;
			}

			if (source == infoBar.getNavBar().getNext()) {
				openURI(pagedList.getNextURI());
				return;
			}

			if (source == infoBar.getNavBar().getLast()) {
				openURI(pagedList.getLastURI());
				return;
			}

			if (source == bottomInfoBar.getNavBar().getFirst()) {
				openURI(pagedList.getFirstURI());
				return;
			}

			if (source == bottomInfoBar.getNavBar().getPrevious()) {
				openURI(pagedList.getPreviousURI());
				return;
			}

			if (source == bottomInfoBar.getNavBar().getNext()) {
				openURI(pagedList.getNextURI());
				return;
			}

			if (source == bottomInfoBar.getNavBar().getLast()) {
				openURI(pagedList.getLastURI());
				return;
			}

		} catch (Throwable t) {
			EditorUtil.hideUpdatePanel();
			t.printStackTrace();
			JOptionPane.showMessageDialog(this, t.getMessage(), "Error",
					JOptionPane.ERROR_MESSAGE);
		}

	}

	public PagedList getPagedList() {
		return pagedList;
	}

	public String getBaseURI() {
		return baseURI;
	}

	@Override
	public void setFilePathProvider(FilePathProvider provider) {
		itemList.setFilePathProvider(provider);

	}

	public InfoBar getInfoBar() {
		return infoBar;
	}

	public void setFullBackground(Color color) {
		setBackground(color);
		infoBar.setBackground(color);
		infoBar.getNavBar().setBackground(color);
		itemList.setFullBackground(color);

	}

	public void setChildrenEditorBackground(Color color) {
		itemList.setChildrenEditorBackground(color);

	}

	public ItemList getItemList() {
		return itemList;
	}

	public void increaseListContent() {
		// pagedList.get
		settingValues = true;
		pagedList.setupPage(true, pagedList.getItemCount() + 1, (int) pagedList
				.getCurrentPageNumber(), baseURI);
		infoBar.setPagedList(pagedList);
		bottomInfoBar.setPagedList(pagedList);
		settingValues = false;
	}

	public void decreaseListContent() {
		// pagedList.get
		settingValues = true;
		pagedList.setupPage(true, pagedList.getItemCount() - 1, (int) pagedList
				.getCurrentPageNumber(), baseURI);
		infoBar.setPagedList(pagedList);
		bottomInfoBar.setPagedList(pagedList);
		settingValues = false;
	}

}
